//
// Operand.hpp for Operand in /home/haz3/poney2/CPU
// 
// Made by Maxime Wojciak
// Login   <wojcia_m@epitech.net>
// 
// Started on  Tue Feb 19 17:29:31 2013 Maxime Wojciak
// Last update Tue Feb 19 19:44:17 2013 Maxime Wojciak
//
#ifndef		__OPERAND__
#define		__OPERAND__

#include	<iostream>
#include	<string>
#include	"../IOperand.hh"

class Operand : public IOperand {

  enum eOperandType {
    Int8,
    Int16,
    Int32,
    Float,
    Double
  };

public:
  operator+(const IOperand &rhs);
  operator-(const IOperand &rhs);
  operator*(const IOperand &rhs);
  operator/(const IOperand &rhs);
  operator%(const IOperand &rhs);
  IOperand * createOperand(eOperandType type, const std::string & value);
  eOperandType getType() const;
  eOperandType toString() const;

private:
  IOperand *createInt8(const std::string & value);
  IOperand *createInt16(const std::string & value);
  IOperand *createInt32(const std::string & value);
  IOperand *createFloat(const std::string & value);
  IOperand *createDouble(const std::string & value);

private:
  eOperandType	_type;
  std::string	_str;
  T		_value;
};

template <>
Operand<char>::Operand() {
  this->_value = 0;
  this->_type = "Int8";
}

template <>
Operand<short>::Operand() {
  this->_value = 0;
  this->_type = "Int16";
}

template <>
Operand<int>::Operand() {
  this->_value = 0;
  this->_type = "Int32";
}

template <>
Operand<float>::Operand() {
  this->_value = 0;
  this->_type = "float";
}

template <>
Operand<double>::Operand() {
  this->_value = 0;
  this->_type = "double";
}

template <typename T>
eOperandType	Operand<T>::getType() const {
  return this->_type;
}

template <typename T>
eOperandType	Operand<T>::toString() const {
  std::ostringstream    StreamStr;

  StreamStr << this->_value;
  return StreamStr.str();
}

template<>

#endif	/* __OPERAND__ */
